package com.etoak.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.etoak.common.core.enums.OrderStateEnum;
import com.etoak.common.web.context.LoginUserContext;
import com.etoak.config.OrderQueueConfig;
import com.etoak.dto.OrderDTO;
import com.etoak.entity.Order;
import com.etoak.mapper.OrderMapper;
import com.etoak.service.OrderItemService;
import com.etoak.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author etoak
 * @since 2025-07-31
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    OrderItemService orderItemService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(OrderDTO orderDTO) {
        // 雪花算法
        String orderNo = IdUtil.getSnowflakeNextIdStr();
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setUserId(Integer.parseInt(LoginUserContext.getUserId()));
        order.setOrderState(OrderStateEnum.NEW.getValue());
        order.setPrepareTime(orderDTO.getPrepareTime());
        order.setCreateTime(DateUtil.now());
        // 保存订单
        this.save(order);
        /* ~~~~~~~~~分割线~~~~~~~~~ */
        // 保存订单项
        orderDTO.getItemList().forEach(item -> item.setOrderNo(orderNo));
        // saveBatch -> 批量保存
        orderItemService.saveBatch(orderDTO.getItemList());

        rabbitTemplate.convertAndSend(OrderQueueConfig.EXCHANGE,OrderQueueConfig.KEY,orderNo,message -> {
            message.getMessageProperties().setDelayLong(10*1000L);
            return message;
        });

    }

    @Override
    public List<Order> getOrders() {

        return this.list();
    }
}
